/**
 * @file TaskQueue.cpp
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-04-05
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "../../include/utils/TaskQueue.h"

namespace wd
{
TaskQueue::TaskQueue(size_t size)
    : mutex_(),
      notFull_(mutex_),
      notEmpty_(mutex_),
      size_(size),
      flag_(true) {}

bool TaskQueue::full()
{
    return size_ == que_.size();
}

bool TaskQueue::empty()
{
    return 0 == que_.size();
}

void TaskQueue::push(Task task)
{
    MutexLockGuard autolock(mutex_);
    while (full()) { // 防止虚假唤醒
        notFull_.wait();
    }
    que_.push(task);

    notEmpty_.notify();
}

TaskQueue::Task TaskQueue::pop()
{
    MutexLockGuard autolock(mutex_);
    // mutex_.lock();

    while (empty() && flag_) {
        notEmpty_.wait();
    }

    if (flag_) {
        Task task = que_.front();
        que_.pop();

        notFull_.notify();
        // mutex_.unlock();
        return task;
    } else {
        // mutex_.unlock();
        return NULL;
    }
}

void TaskQueue::wakeup_empty()
{
    notEmpty_.notifyall();
}

void TaskQueue::set_flag(bool flag)
{
    flag_ = flag;
}

} // end of namespace wd
